Node.js 環境建置、邏輯運算、位元運算


Posted by saffran on 2020-12-01

該如何執行 JavaScript?

一直以來,JavaScript 都只能在瀏覽器上面執行

直到出現了 Node.js

Node.js 是一個執行環境(不是一個程式語言),能夠讓 JavaScript 在瀏覽器外面執行,也就是可以跑在我的電腦上

在瀏覽器裡寫 JavaScript

方法一:用 vim 寫 JS 程式碼

  1. 在 CLI 用 vim 建立(開啟)一個檔案叫做 index.html
    vim index.html
    
  2. 在 vim 裡面輸入 <script></script> 的標籤之後,就可以開始在 <script></script> 標籤裡面寫 JS 程式碼了
    (因為這個是 html 檔案,所以要用 <script></script> 標籤把 JS 程式碼包起來)
    <script>
    console.log('Monday')
    </script>
    
  3. 在瀏覽器開啟 index.html,打開 devtool,就可以看到剛剛寫的程式碼了
    ## 方法二:直接在瀏覽器的 Console 寫 JS 程式碼

用 Node.js 執行 JS

方法一:

  1. 在 CLI 用 vim 建立(開啟)一個檔案叫做 index.js
    vim index.js
    
  2. 就可以直接開始寫 JS 程式碼了
    console.log('Monday')
    
  3. 回到 CLI 輸入 node index.js,就可以看到剛剛我想要印出的東西了
    node 檔案名稱
    

方法二:

要用 Node.js 執行 JS,還有另一種方式是:

在 CLI 輸入 node 按下 Enter 後,就可以開始寫 JS 了

例如:

輸入 console.log(789) 後就會印出 789

下面那行 undefined 可以不用理它,它只是 console.log(789) 這個函式的回傳值

要離開 Node.js,就按下 ctrl + C

邏輯運算:|| 與 && 的短路性質

什麼是短路性質呢?

舉例來說

|| or

範例一:
當我在 Node.js 輸入 5 || 30
因為「or」就是「只要其中一個是 true,整個句子就都是 true」

因此,當它跑到 5 時,就是 true 了,所以就不會再去看後面的值,就會直接回傳 5

5 || 30

範例二:
當我在 Node.js 輸入 false || 20
因為「or」就是「只要其中一個是 true,整個句子就都是 true」

因此,它要跑到 20 時,才會知道整個句子的結果是 true ,所以就會回傳 20

false || 20

範例三:
當我在 Node.js 輸入 0 || console.log(789)
因為「or」就是「只要其中一個是 true,整個句子就都是 true」

因此,它看完 0 之後(0 是 false),要再跑到 console.log(789) 時,才會知道整個句子的結果是 true ,所以就會回傳 789

0 || console.log(789)

&& and

範例一:
當我在 Node.js 輸入 false && 50
因為「and」就是「一定要兩個都是 true,整個句子才會是 true」

因此,當它跑到 false 時,就是 false 了,所以就不會再去看後面的值,就會直接回傳 false

false && 50

範例二:
同樣地,輸入 0 && 8999 會回傳 0,因為 0 就已經是 false 了

0 && 8999

範例三:
當我在 Node.js 輸入 8 && 27
因為「and」就是「一定要兩個都是 true,整個句子才會是 true」

因此,它必須把兩個值都看完

  • 8 是 true
  • 但是,還是要跑到 27,才確定整個句子的結果是 true,因此會回傳 27
8 && 27

看它最後跑到哪個值,就回傳哪個值--> 這個就叫做「短路性質」(因為有時候根本不需要看後面的值,就可以決定整個句子的值是 true 還是 false)

true 真的值

true 就是「真的」值

false 假的值

直覺覺得它是「沒有」的東西,就是 false(假的值)

例如:0、空字串、null

位移運算子

位移運算,是位元運算的其中一塊:是針對「位元(每一個 bit)」來做操作,而不是針對整體

對「2 進位」來說
0100 = 2^2 = 4
1000 = 2^3 = 8

0100 往左移 1 位,就是 1000,也就是「乘以 2」

因此,對「2 進位」來說

  • 把每一個位元都往左移 1 位,就是「* 2」
  • 把每一個位元都往右移 1 位,就是「/ 2」

運用「位元運算」的性質,來達到「* 2」、「/ 2」

例如:

往左移 <<

  • 把 10 往左移 1 位,會回傳 20
    10 * 2^1
    10 << 1
    
  • 把 10 往左移 3 位,會回傳 80
    10 * 2^3
    10 << 3
    
  • 把 1 往左移 10 位,會回傳 1024
    1 * 2^10
    1 << 10
    

往右移 >>

往右移如果不能整除的話,就會無條件捨去

  • 把 1024 往右移 1 位,會回傳 512
    10 / 2^1
    1024 >> 1
    
  • 把 9 往右移 1 位,會回傳 4
    9 / 2^1 = 4.5 無條件捨去 = 4
    9 >> 1
    
    ## 位移運算子的優點
    使用「左移、右移」運算子的方式來乘以 2、除以 2,比起直接使用「* 2」、「/ 2」,效能更快

原因是:二進位對電腦來說,是最原始的形式,因此效能通常都會最好

位元運算的 and、or、xor 與 not

先把數字變成二進位,再針對二進位的每一個位數去做運算

只有一個 & 時,就會做「位元運算」

& 位元運算的 and

例如:
之前在講邏輯運算子時,輸入 10 && 15 會回傳 15,因為這裡做的是「邏輯運算」

但是
如果是輸入 10 & 15 會回傳 10,因為這裡做的是「位元運算」

10 & 15

運算的模式如下

會先把 10 和 15 變成二進位:

  • 10 會是 1010
  • 15 會是 1111

然後再針對每一個位元去做 & 的運算,因為這裡是使用 & (and)

  • 第 1 個位數:0 & 1 會是 0
  • 第 2 個位數:1 & 1 會是 1
  • 第 3 個位數:0 & 1 會是 0
  • 第 4 個位數:1 & 1 會是 1

所以,最後的結果就是 1010 也就是 10,因此就是回傳 10

| 位元運算的 or

例如:
輸入 10 | 15 會回傳 15,因為這裡做的是「位元運算」

10 | 15

^ 位元運算的 xor(exclusive or)

兩個東西是一樣的話,就會回傳 0:

  • 兩個都是 1 的話,會回傳 0
  • 兩個都是 0 的話,會回傳 0

兩個東西不一樣的話,就會回傳 1

  • 0, 1 就會回傳 1
  • 1, 0 就會回傳 1

例如:
輸入 10 ^ 15 會回傳 5,因為這裡做的是「位元運算」

10 ^ 15

~ 位元運算的 not

在邏輯運算中,輸入 !15 會回傳 false

但如果是輸入 ~15,會回傳 -16,因為做的是「位元運算」

為什麼會是 -16 呢?

因為把 15 轉成二進位就會是 1111
乍看之下是 1111,但是因為在 JavaScript 的數字是有 32 個 bit
所以,1111 其實是 000000000000000000000000000000001111(前面還有很多很多個 0)

所以把 000000000000000000000000000000001111 做 not 的運算後就會是 111111111111111111111111111111110000 = -16

可以把 & 當作是「位元遮罩」來用

1010 and 1 就會是 0000
1011 and 1 就會是 0001

因為只有「and 1」,前面每個位數的結果都一定會是 0,因此就只需要看最後一個位數

  • 如果最後一個位數是 0,結果就會是 0
  • 如果最後一個位數是 1,結果就會是 1

因此,就可以推導出這樣的公式:
A & 1 => 0 代表「A 的最後一個數字是 0」
A & 1 => 1 代表「A 的最後一個數字是 1」

A & 8 => 8 代表「A 的第四個位數是 1」

因為 8 轉成二進位是 1000,所以只需要看「第四個位數」來決定最後結果(其他位數經過 and 的運算後,都會是 0)

這樣的公式可以用在哪裡?

二進位的每個位數分別代表

1 2 4 8 16 32...

仔細觀察會發現,只有第一個位數是奇數(也就是 1)

所以

如果二進位的最後一個數字是 0 的話,例如 1010,那它轉成十進位後就一定會是「偶數」

因為 1010 轉成十進位會是:
2^0 0 是 0 (唯一有可能是奇數的位數是 0)
加上 2^1
1 (是偶數)
加上 2^2 0 (是 0)
加上 2^3
1 (是偶數)

所以最後的結果就會是 0 + 2 + 0 + 8 = 10(偶數)

如果二進位的最後一個數字是 1 的話,例如 1011,那它轉成十進位後就一定會是「奇數」

因為 1011 轉成十進位會是:
2^0 1 是 1 (唯一有可能是奇數的位數是 1)
加上 2^1
1 (是偶數)
加上 2^2 0 (是 0)
加上 2^3
1 (是偶數)

所以最後的結果就會是 1 + 2 + 0 + 8 = 11(奇數)

那我要怎麼知道「二進位的最後一個數字」是 0 還是 1 呢?

這時,就可以用到上面推導出來的公式:
A 是一個十進位的數字
(在做 & 運算前,電腦會自動先把 A 轉成二進位)

A & 1 => 0 代表「A 的最後一個數字是 0」,那就代表「轉成十進位後,會是一個偶數」

例如:

  • 輸入 38 & 1,會回傳 0 (因為 38 是偶數)
    ### A & 1 => 1 代表「A 的最後一個數字是 1」,那就代表「轉成十進位後,會是一個奇數」
    例如:
  • 輸入 39 & 1,會回傳 1 (因為 39 是奇數)

結論:用「位元運算」,我可以很快的判斷出這個數字是「偶數」還是「奇數」


#node.js







Related Posts

How to Set Up Firewall with UFW on Ubuntu 20.04

How to Set Up Firewall with UFW on Ubuntu 20.04

初見狀態管理工具 Vuex (1) 初步接觸與安裝導入

初見狀態管理工具 Vuex (1) 初步接觸與安裝導入

什麼是 jQuery ?

什麼是 jQuery ?


Comments